#####################################################################
# Product:      KnowledgeEngine (Plone Edition)
#
# File:         CreateAssessment.py
#
# Copyright:    Copyright (c) 2004, Faulkner Technologies
#
# Author:       James Davies
#
# Description:  This file defines the CreateAssessment class, a simple
#               action to create new assessments
#
# See Also:     Action, Event
#####################################################################

#####################################################################
## Knowledge Engine Library Imports
from Products.KnowledgeEngine.Common import *
from Products.KnowledgeEngine.Core import *
from Products.KnowledgeEngine.Action import Action, ActionInfo
from Products.KnowledgeEngine.PropertyDefinition import *
from Products.KnowledgeEngine.PropertyTypes import *
from Products.KnowledgeEngine.PropertyFormats import *
from Products.KnowledgeEngine.PropertyStructures import *

#####################################################################
## Zope Library Imports
from Globals import DTMLFile
from App.ImageFile import ImageFile

#####################################################################
## Python Library Imports
# (none)

#####################################################################
## CreateAssessmentInfo Class Definition
class CreateAssessmentInfo(ActionInfo):
    """
        Defines the class info methods, defining information about
        the class without needing an instance of the class
    """
    
    #---------------------------------------------------------------#
    
    def getClassName(self):
        """
            Returns the name of the class for which 
            we are providing information.
        """
        return "CreateAssessment"

    #---------------------------------------------------------------#

    def getDisplayName(self):
        """
            Return a friendly name for the class instances
            (this is used for displaying in lists etc)
        """
    
        return "CreateAssessment"
        
    #---------------------------------------------------------------#

    def getIdentityType(self):
        """
            Return the identity type.  
        """
        
        return "CreateAssessment"
        
    #---------------------------------------------------------------#
    
    def getClassIcon(self):
        """
            Return the appropriate icon file for the class.
        """
        
        return ImageFile('skins/CreateAssessment_icon.gif', globals())
   
    #---------------------------------------------------------------#

    def onConfigureProperties(self):
        """
            Automatically called by the Knowledge Engine once
            the class has been loaded.  Use this method to register 
            class specific properties using the PropertyReflection interface.
            
            If this class is sub-classed, a call must be made to
            the super-class to ensure super-class properties are
            correctly registered
            
            NOTE: This method is called before ClassInfo.onAfterStartup()            
        """

        #initialise the super-class properties for reflection
        ActionInfo.onConfigureProperties(self)
        
        
        self.addPropertyDefinition(PropertyDefinition(
            identity="newModelIdentity", 
            displayName="New Model Identity", 
            description="Leave blank for current model. Ignored if 'Clone Assessment' is enabled", 
            defaultValue="",
            propertyType=pt_STRING, 
            propertyFormat=pf_TEXT_SINGLELINE,
            propertyStructure=ps_ATOMIC
        ))
        
        self.addPropertyDefinition(PropertyDefinition(
            identity="cloneAssessment", 
            defaultValue="",
            displayName="Clone Data", 
            description="Copies this assessments component states into the new assessment", 
            propertyType=pt_BOOLEAN, 
            propertyFormat=pf_CHECKBOX,
            propertyStructure=ps_ATOMIC
        ))   
             
        self.addPropertyDefinition(PropertyDefinition(
            identity="launchAssessment", 
            defaultValue="",
            displayName="Launch Immediately", 
            description="Begins the new assessment immediately", 
            propertyType=pt_BOOLEAN, 
            propertyFormat=pf_CHECKBOX,
            propertyStructure=ps_ATOMIC
        ))  
        
        
        
        self.addPropertyDefinition(PropertyDefinition(
            identity="entity", 
            defaultValue="",
            displayName="Assign To Entity", 
            description="Leave blank for (Triggering User)", 
            propertyType=pt_STRING, 
            propertyFormat=pf_TEXT_SINGLELINE,
            propertyStructure=ps_ATOMIC
        ))        

    #---------------------------------------------------------------#

#####################################################################
## CreateAssessment Action Class Definition
class CreateAssessment(Action):
    """
        Create Assessment Action
    """

    #---------------------------------------------------------------#

    #ABSTRACT TRANSIENT: a ClassInfo implementation instance to provide info about this class
    _CLASSINFO = CreateAssessmentInfo()
    
    #---------------------------------------------------------------#

    def __init__(self, id, identity):
        "Constructor for the Folder"        

        Action.__init__(self, id, identity)
                
        #perform onAfterInstanciation processing
        self.onAfterInstanciation()

    #---------------------------------------------------------------#

    def onAfterInstanciation(self):
        """
            Handle Knowledge Engine specific actions after this object 
            has been loaded into memory.  
            
            This is useful for performing backwards compatibility
        """        
        
        #perform default processing
        Action.onAfterInstanciation(self)
        
    #---------------------------------------------------------------#
    
    def getCloneAssessment(self):
        """ Should we clone all data? """
        
        return getattr(self.aq_explicit, "cloneAssessment", False)
    
    #---------------------------------------------------------------#
    
    def getLaunchAssessment(self):
        """ Should we launch this assessment immediately """
        
        return getattr(self.aq_explicit, "launchAssessment", False)
    
    #---------------------------------------------------------------#
    
    def getNewModelIdentity(self):
        """ Returns the identity of the model we are creating an assessment for """
        
        return getattr(self.aq_explicit, 'newModelIdentity', None)
    
    #---------------------------------------------------------------#
    
    def setNewModelIdentity(self, value):
        """ Sets the new model identity """
        
        self.newModelIdentity = value
        
    
    #---------------------------------------------------------------#    
    
    def getEntity(self):
        """ Returns the name of the identity the assessment is to be created for """
        
        return getattr(self.aq_explicit, 'entity', None)
    
    #---------------------------------------------------------------#
    
    def execute(self, assessment, user = None, previousActionSuccess = true):
        """
           Sends the message for this log action to the stdout
        """            

        modelIdentity = self.getNewModelIdentity()
        entity        = self.getEntity()
        if not entity:  # No entity specified, use the user that opened the assessment
            entity = assessment.getCreatedBy()


        # Get the specified model. If no model is specified, use the current assessments model.
        if modelIdentity:
            model = self.getComponentByIdentity( modelIdentity )
        else:
            model = assessment.getModel()
        

        #assume event handled correctly
        actionSuccess = true   

        assessmentStorageService = self.knowledgeengine_assessmentstorageservice
        
        # Should we clone this assessment or create a blank one?
        if self.getCloneAssessment():
            newAssessment = assessmentStorageService.createAssessment( model, entity, cloneAssessmentIdentity=assessment.getIdentity() )
        else:
            newAssessment = assessmentStorageService.createAssessment( model, entity )
        
        # Set the Creator (Username)
        newAssessment.setCreatedBy( entity )

        # Add to the new users personal repository
        assessmentStorageService.addAssessmentToRepository( newAssessment, entity )

        # Make sure we save the assessment
        assessmentStorageService.saveAssessment( newAssessment )
        
        if model.isEventEnabled("onAfterCreateAssessmentInPersonalRepository"):
            model.getEnabledEvent("onAfterCreateAssessmentInPersonalRepository").execute(assessment, user)
            print "Event IS Enabled"
        else:
            print "Event not enabled!"        
                
        
        # Do we need to jump directly to the new assessment?
        if self.getLaunchAssessment():
            
            # HACK - Set a REQUEST variable to signal myknowledge_processor the URL to redirect to
            url = model.absolute_url() + "/assess?assessmentIdentity=" + newAssessment.getIdentity()
            self.REQUEST.set('_action_redirect', url)
            
        

        return actionSuccess
        
    #---------------------------------------------------------------#

#####################################################################
## Class Initialisation

# Register Class Information with the Knowledge Engine
registerGenericObjectClass(CreateAssessment)

#####################################################################